#include <gloox/client.h>
#include <gloox/connectionlistener.h>
#include <gloox/messagehandler.h>
#include <gloox/mucroom.h>
#include <gloox/mucroomhandler.h>
#include <iostream>
#include <xercesc/util/PlatformUtils.hpp>
#include <QtCore/qobject.h>
#include <kurl.h>
#include <syndication/loader.h>

using namespace gloox;
using namespace std;

class StdErrLogHandler : public LogHandler
{
  public:
    virtual void handleLog( LogLevel level,
                            LogArea area,
    const std::string & message )
    {
        cerr << message << endl;
    }
};

class Bot : public QObject, public MessageHandler, public ConnectionListener, public MUCRoomHandler
{
    Q_OBJECT

  public:
    Bot(string& password)
    {
        loader = Syndication::Loader::create();
        QObject::connect(
            loader,
            SIGNAL(loadingComplete(Syndication::Loader*, Syndication::FeedPtr, Syndication::ErrorCode)),
            this,
            SLOT(slotLoadingComplete(Syndication::Loader*, Syndication::FeedPtr, Syndication::ErrorCode))
        );

        JID jid("vxbot@jabber.org");
        JID jid_muc("fragile-bot@conference.jabber.org/vxbot");
        j = new Client(jid, password);
        r = new MUCRoom(j, jid_muc, this);

        // Logging to STDERR
        StdErrLogHandler* lh = new StdErrLogHandler();
        j->logInstance().registerLogHandler( LogLevelDebug, LogAreaAll,
                                             lh );

        j->registerConnectionListener( this );
        j->registerMessageHandler( this );
        j->setPresence( PresenceAvailable, 5 );
        j->connect();
    }

    virtual void handleMessage( Stanza* stanza,
                                MessageSession* session = 0 )
    {
        Stanza *s = Stanza::createMessageStanza( stanza->from().full(),
                                                 "hello world" );
        j->send( s );
    }

    virtual void onConnect()
    {
        r->join();
        loader->loadFrom(KUrl("https://code.google.com/feeds/p/fragile-bot/svnchanges/basic"));
    }
    virtual bool onTLSConnect( const CertInfo &info )
    {
        // Always accept certificates
        return true;
    }
    virtual void onDisconnect( ConnectionError e )
    {
    }

    virtual void handleMUCParticipantPresence (MUCRoom *room, const MUCRoomParticipant participant, Presence presence)
    {

    }

    virtual void handleMUCMessage(MUCRoom *room, const std::string &nick, const std::string &message, bool history, const std::string &when, bool privateMessage)
    {
    }
    virtual bool handleMUCRoomCreation (MUCRoom *room) {
        return true;
    }
    virtual void handleMUCSubject (MUCRoom *room, const std::string &nick, const std::string &subject)
    {
    }
    virtual void handleMUCInviteDecline (MUCRoom *room, const JID &invitee, const std::string &reason)
    {
    }
    virtual void handleMUCError (MUCRoom *room, StanzaError error)
    {

    }

    virtual void handleMUCInfo (MUCRoom *room, int features, const std::string &name, const DataForm *infoForm)
    {

    }

    virtual void handleMUCItems (MUCRoom *room, const StringMap &items)
    {

    }

  public slots:
    void slotLoadingComplete(Syndication::Loader* loader,
                             Syndication::FeedPtr feed,
                             Syndication::ErrorCode status)
    {
        if (status != Syndication::Success)
            return;

        QString title = feed->title();
        cout << title.toStdString() << endl;
    }

  private:
    Client* j;
    MUCRoom* r;
    Syndication::Loader* loader;
};

int main( int argc, char* argv[] )
{
    if (argc < 2) {
        cout << "Password required." << endl;
        return 1;
    }
    string password;
    password.assign(argv[1]);

    Bot b(password);
    return 0;
}

#include "vxbot.moc"
